JavaScript 中的物件即透過繼承 原型(Prototype)
的機制,使其能夠使用繼承而來的屬性和方法。今天除了介紹 原型(Prototype)
是什麼和 原型鍊(Prototype chain)
的運作方式,透過範例了解物件之間的繼承關係,也會解釋 JavaScript 的原型架構與一般認知上的物件導向的差別。
在 JavaScript 中,每個物件都有一個 原型(Prototype)
。原型是一個物件,它包含屬性和方法,且原型物件可能上也可能有它自己的原型。當你訪問一個物件的屬性或方法時,JavaScript 引擎會先在這個物件上尋找,如果找不到,它就會在該物件的原型物件查找是否有對應的屬性或方法。
原型物件可能也包含了另一個原型。因此如果 JavaScript 引擎在該原型物件還是找不到屬性或方法,它就會繼續往上查找,依此類推,直到找到屬性或方法。我們稱這一層一層的關係為 原型鍊(Prototype chain)
,而原型鍊的最末端就是 Object 原型,因為所有物件(例如陣列、函式)其實都是繼承 Object 而來的。
就以陣列為例子,
我們知道陣列也是一個物件,而它會有一個 Array 的原型,裡面有許多方法可用。
而 Array 原型中又有一個 Object 的原型,因為陣列是繼承物件而來。
而我們在 第19天 提到的包裝物件,其實也是基於原型實作而來的。
JavaScript 是一個物件導向(Object-Oriented Programming,簡稱OOP)的程式語言,但它的物件導向模型與傳統的物件導向程式語言(如 Java 或 C++)其實還是有所不同的。
以下是來自 MDN文件 的解釋:
傳統的 OOP 都是先定義了類別(class),接著在建立物件實例之後,在類型上定義的所有屬性與函式均複製到此實例。但 JavaScript 不會複製這些屬性與函式,卻是在物件實例與其建構子之間設定連結 (原型鍊中的連結),只要順著原型鍊就能在建構子之中找到屬性與函式。
簡單來說,JavaScript 是基於原型架構的程式語言,並不是傳統認知上的類別(class)的概念。
但要注意的是 JavaScript 在 ES6 引入了 class
的關鍵字,用來作為建立新物件的模板。它能將程式碼封裝起來便於處理。它提供了一種更接近傳統類別(class)的語法,但實際上,它只是原型的一個語法糖(syntactical sugar)。使用 class 創建的物件仍然基於原型。
今天介紹了 原型(Prototype)
的概念與繼承關係,了解到 JavaScript 是透過 原型鍊(Prototype chain)
的運作方式來查找對應的屬性和方法。也提到了 JavaScript 的原型架構與一般物件導向的差別。其中關於 JavaScript 中的 class 語法應該會在之後再拉一天在詳談了。那麼今天就到這邊,明天見~